#import "GLView.h"

#define GL_RENDERBUFFER 0x8d41

@implementation GLView

//@synthesize accel;

+ (Class) layerClass
{
    return [CAEAGLLayer class];
}

- (id) initWithFrame: (CGRect) frame
{
    if (self = [super initWithFrame:frame])
    {
        CAEAGLLayer* eaglLayer = (CAEAGLLayer*) self.layer;
        eaglLayer.opaque = YES;

        EAGLRenderingAPI api = kEAGLRenderingAPIOpenGLES1;
        m_context = [[EAGLContext alloc] initWithAPI:api];
        
        if (!m_context) {
            api = kEAGLRenderingAPIOpenGLES1;
            m_context = [[EAGLContext alloc] initWithAPI:api];
        }
        
        if (!m_context || ![EAGLContext setCurrentContext:m_context]) {
            [self release];
            return nil;
        }
		
		m_resourceManager = CreateResourceManager();

        if (api == kEAGLRenderingAPIOpenGLES1) {
            NSLog(@"Using OpenGL ES 1.1");
            m_renderingEngine = ES1::CreateRenderingEngine(m_resourceManager);
        } else {
            NSLog(@"Using OpenGL ES 2.0");
//            m_renderingEngine = ES2::CreateRenderingEngine();
        }
		
		m_applicationEngine = CreateApplicationEngine(m_renderingEngine);
		
		m_locationManager = [[CLLocationManager alloc] init];
		
		
#if TARGET_IPHONE_SIMULATOR
        BOOL compassSupported = NO;
        BOOL accelSupported = NO;
#else
        BOOL compassSupported = m_locationManager.headingAvailable;
        BOOL accelSupported = YES;
#endif
		
		if (compassSupported) {
			NSLog(@"Compass is supported.");
			m_locationManager.headingFilter = kCLHeadingFilterNone;
			m_locationManager.delegate = self;
			[m_locationManager startUpdatingHeading];
		} else {
			NSLog(@"Compass is NOT supported.");
		}
		
		if (accelSupported) {
            NSLog(@"Accelerometer is supported.");
            float updateFrequency = 60.0f;
            m_filter = [[LowpassFilter alloc] initWithSampleRate:updateFrequency
												 cutoffFrequency:5.0];
            m_filter.adaptive = YES;
			
            [[UIAccelerometer sharedAccelerometer] setUpdateInterval:1.0 / updateFrequency];
            [[UIAccelerometer sharedAccelerometer] setDelegate:self];
        } else {
            NSLog(@"Accelerometer is NOT supported.");
        }

		
        [m_context
            renderbufferStorage:GL_RENDERBUFFER
            fromDrawable: eaglLayer];
                
        int width = CGRectGetWidth(frame);
        int height = CGRectGetHeight(frame);
        m_applicationEngine->Initialize(width, height);
		
		
		resetMagnButton.hidden = NO;
		resetZeroButton.hidden = NO;
        
        [self drawView: nil];
        m_timestamp = CACurrentMediaTime();
        
        CADisplayLink* displayLink;
        displayLink = [CADisplayLink displayLinkWithTarget:self
                                     selector:@selector(drawView:)];
        
        [displayLink addToRunLoop:[NSRunLoop currentRunLoop]
                     forMode:NSDefaultRunLoopMode];
		
    }
    return self;
}

- (id) initWithCoder:(NSCoder*)coder
{
	if ((self = [super initWithCoder:coder]))
	{
//		CAEAGLLayer* eaglLayer = (CAEAGLLayer*) self.layer;
//        eaglLayer.opaque = YES;
//		
//        EAGLRenderingAPI api = kEAGLRenderingAPIOpenGLES1;
//        m_context = [[EAGLContext alloc] initWithAPI:api];
//        
//        if (!m_context) {
//            api = kEAGLRenderingAPIOpenGLES1;
//            m_context = [[EAGLContext alloc] initWithAPI:api];
//        }
//        
//        if (!m_context || ![EAGLContext setCurrentContext:m_context]) {
//            [self release];
//            return nil;
//        }
//		
//		m_resourceManager = CreateResourceManager();
//		
//        if (api == kEAGLRenderingAPIOpenGLES1) {
//            NSLog(@"Using OpenGL ES 1.1");
//            m_renderingEngine = ES1::CreateRenderingEngine(m_resourceManager);
//        } else {
//            NSLog(@"Using OpenGL ES 2.0");
//			//            m_renderingEngine = ES2::CreateRenderingEngine();
//        }
//		
//		m_applicationEngine = CreateApplicationEngine(m_renderingEngine);
//		
//		m_locationManager = [[CLLocationManager alloc] init];
//		
//		
//#if TARGET_IPHONE_SIMULATOR
//        BOOL compassSupported = NO;
//        BOOL accelSupported = NO;
//#else
//        BOOL compassSupported = m_locationManager.headingAvailable;
//        BOOL accelSupported = YES;
//#endif
//		
//		if (compassSupported) {
//			NSLog(@"Compass is supported.");
//			m_locationManager.headingFilter = kCLHeadingFilterNone;
//			m_locationManager.delegate = self;
//			[m_locationManager startUpdatingHeading];
//		} else {
//			NSLog(@"Compass is NOT supported.");
//		}
//		
//		if (accelSupported) {
//            NSLog(@"Accelerometer is supported.");
//            float updateFrequency = 60.0f;
//            m_filter = [[LowpassFilter alloc] initWithSampleRate:updateFrequency
//												 cutoffFrequency:5.0];
//            m_filter.adaptive = YES;
//			
//            [[UIAccelerometer sharedAccelerometer] setUpdateInterval:1.0 / updateFrequency];
//            [[UIAccelerometer sharedAccelerometer] setDelegate:self];
//        } else {
//            NSLog(@"Accelerometer is NOT supported.");
//        }
//		
//		
//        [m_context
//		 renderbufferStorage:GL_RENDERBUFFER
//		 fromDrawable: eaglLayer];
//		
////        int width = CGRectGetWidth(frame);
////        int height = CGRectGetHeight(frame);
//        m_applicationEngine->Initialize(320, 480);
//		
//		
//		resetMagnButton.hidden = NO;
//		resetZeroButton.hidden = NO;
//        
//        [self drawView: nil];
//        m_timestamp = CACurrentMediaTime();
//        
//        CADisplayLink* displayLink;
//        displayLink = [CADisplayLink displayLinkWithTarget:self
//												  selector:@selector(drawView:)];
//        
//        [displayLink addToRunLoop:[NSRunLoop currentRunLoop]
//						  forMode:NSDefaultRunLoopMode];
		
	}
	return self;
}



- (void) dealloc
{
	if ([EAGLContext currentContext] == m_context) {
		[EAGLContext setCurrentContext:nil];
	}

	[m_filter release];
	[m_locationManager release];
	[m_context release];
	[super dealloc];
}

- (void) drawView: (CADisplayLink*) displayLink
{
    if (displayLink != nil) {
        float elapsedSeconds = displayLink.timestamp - m_timestamp;
        m_timestamp = displayLink.timestamp;
        m_applicationEngine->UpdateAnimation(elapsedSeconds);
    }
	
    m_applicationEngine->Render(m_magValue, m_accelValue);
    [m_context presentRenderbuffer:GL_RENDERBUFFER];
}


- (IBAction)onResetZeroButton:(UIButton *)sender
{
}

- (IBAction)onResetMagnButton:(UIButton *)sender
{
}



- (void) locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading*)heading
{
	// Use magneticHeading
	CLLocationDirection degrees = heading.magneticHeading;
	m_magValue = (float)-degrees;
}

- (void) accelerometer: (UIAccelerometer*) accelerometer
         didAccelerate: (UIAcceleration*) acceleration
{
    [m_filter addAcceleration:acceleration];

	// landscape 모드에서의 가속도 값이다.
	// y-z면을 기준으로 하여 tan를 계산한다.
	// tan(theta) = y/x(높이/밑변)이다. 탄젠트의 invert하면 (theta)=atan(y/x)가 된다.
	//
	float x = m_filter.y;
	float y = m_filter.z;
	m_accelValue = atan2(y, -x) * 180.0f / Pi;
	
	// landscape 모드에서의 가속도 값이다.
	// x-z면을 기준으로 하여 tan를 계산한다.
	//	float x = m_filter.x;
	//	float y = m_filter.z;
	//	m_accelValue = atan2(y, -x) * 180.0f / Pi;
}


- (void) touchesBegan: (NSSet*) touches withEvent: (UIEvent*) event
{
    UITouch* touch = [touches anyObject];
    CGPoint location  = [touch locationInView: self];
    m_applicationEngine->OnFingerDown(ivec2(location.x, location.y));
}

- (void) touchesEnded: (NSSet*) touches withEvent: (UIEvent*) event
{
    UITouch* touch = [touches anyObject];
    CGPoint location  = [touch locationInView: self];
    m_applicationEngine->OnFingerUp(ivec2(location.x, location.y));
}

- (void) touchesMoved: (NSSet*) touches withEvent: (UIEvent*) event
{
    UITouch* touch = [touches anyObject];
    CGPoint previous  = [touch previousLocationInView: self];
    CGPoint current = [touch locationInView: self];
    m_applicationEngine->OnFingerMove(ivec2(previous.x, previous.y),
                                      ivec2(current.x, current.y));
}

@end


